﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace FolderSynchronizer
{
	/// <summary>
	/// Класс, реализующий метод копирования в конечную папку.
	/// </summary>
	public class TargetStager
	{
		private readonly ISynchronizer copier;
		private readonly SynchronizersUtility preCopier;
		private readonly DirectoryInfo targetDir;
		private readonly List<DirectoryInfo> targetDirInfo;
		private readonly List<FileInfo> filesInTargetFolder;
		private readonly DirectoryInfo[] dirs;
		private FileInfo file;
		private DirectoryInfo folder;
		private string relativfolderName;
		private string nameExludeFolder;

		/// <summary>
		/// Конструтор
		/// </summary>
		/// <param name="copier">Объект, осуществляющий копирование, типа ISynchronizer</param>
		public TargetStager(ISynchronizer copier)
		{
			this.copier = copier;
			preCopier = new SynchronizersUtility(copier.PathToTempFolder, copier.TargetFolder, copier.Settings, true, true);

			if (Directory.Exists(copier.TargetFolder))
			{
				targetDir = new DirectoryInfo(copier.TargetFolder);
			    targetDirInfo = copier.TargetDirInfo;
				dirs = targetDir.GetDirectories(".", SearchOption.AllDirectories);
				filesInTargetFolder = copier.TargetPathFiles;
			}
			else
			{
				targetDirInfo = new List<DirectoryInfo>();
				filesInTargetFolder = new List<FileInfo>();
				dirs = null;
				targetDir = null;
			}
		}

		/// <summary>
		/// Начать копирование в конечную папку.
		/// </summary>
		public void Start()
		{
		    PrepareForCopying();
			this.preCopier.Compute();
		}

		private void PrepareForCopying()
		{
			if (copier.FullMatchDirectories)
			{
				DeleteUnnecessaryFiles();
				DeleteUnnecessaryFolders();
			}
			else
			{
				CleanFolders();
			}
		}

		private void CleanFolders()
		{
			if ((copier.PureFolders != null) && (dirs != null))
			{
				SeriesOfClean();
			}
		}

		private void SeriesOfClean()
		{
			foreach (DirectoryInfo dr in dirs)
			{
				foreach (string name in copier.PureFolders)
				{
					nameExludeFolder = name;
					folder = dr;
					ConditionOfCleanFolder();
				}
			}
		}

		private void ConditionOfCleanFolder()
		{
			relativfolderName = folder.FullName.Substring(targetDir.FullName.IndexOf(targetDir.Name, StringComparison.Ordinal) + targetDir.Name.Count() + 1);
			if (relativfolderName == nameExludeFolder)
			{
				folder.Delete(true);
			}
		}

		private void DeleteUnnecessaryFolders()
		{
			foreach (DirectoryInfo directoryInfo in targetDirInfo)
			{
				string relativePathToFolder = directoryInfo.FullName.Substring(targetDir.FullName.IndexOf(targetDir.Name, StringComparison.Ordinal) + targetDir.Name.Count() + 1);

				if (!Directory.Exists(Path.Combine(copier.SourceFolder, relativePathToFolder)))
				{
					copier.DeleteFolder(directoryInfo.FullName);
				}
			}
		}

		private void DeleteUnnecessaryFiles()
		{
			foreach (FileInfo fileInfo in this.filesInTargetFolder)
			{
				this.file = fileInfo;
				CoditionOfDeleteFile();
			}
		}

		private void CoditionOfDeleteFile()
		{
			string relativePathToFile =
				file.FullName.Substring(targetDir.FullName.IndexOf(targetDir.Name, StringComparison.Ordinal) + targetDir.Name.Count() + 1);
			if (!File.Exists(Path.Combine(copier.SourceFolder, relativePathToFile)))
			{
				file.Delete();
			}
		}
	}
}
